//------------------------------------------------------------------------
// Abstract: Define of relative Structure of database
//
// Authoring: XiaoHanxiong
//
// Time: 2014.03.14
//
// Static test:
//
// Version history:
//		Ver_1.0	: 2014.03.14	XiaoHanxiong
//------------------------------------------------------------------------
#ifndef __Database_DBStructure_h_
#define __Database_DBStructure_h_

#include "Stdafx.h"

namespace Database
{
	// Field data user type
	typedef enum _DATABASE FieldType
	{
		EFT_NULL = 0x0,
		EFT_BOOL,
		EFT_INT8, EFT_INT16, EFT_INT32, EFT_INT64, 
		EFT_UINT8, EFT_UINT16, EFT_UINT32, EFT_UINT64, 
		EFT_FLOAT, EFT_DOUBLE,
		EFT_CHAR, EFT_TEXT,
		EFT_BLOB,
		EFT_DATE,
	}DataUserType;

	
	// Field data constraint
	typedef enum _DATABASE FieldConstraint
	{
		EFC_None = 0x0,
		EFC_NotNull = 0x1,
		EFC_Primary = 0x2,
		EFC_Foreign = 0x4
	}DataConstraint;



	// Data container
	class _DATABASE DataContainer
	{
	public:
		// Copy Constructor
		DataContainer(const DataContainer& data);
		// Default Constructor
		DataContainer();
		// Destructor
		~DataContainer();

	public:
		// Flag for mark the data type
		typedef enum DataFlag{ _Null, _Int64, _Double, _Blob, _String }Flag;
		// Blob and text type
		typedef struct DataBlob
		{
			int m_size;
			void* m_ptr;
		}Blob, String;
		// Integer number type
		typedef unsigned __int64 Uint64;
		// Float point number type
		typedef double Double;

	public:
		// Data container
		typedef union DataValue
		{
			Uint64 um_uint64;
			Double um_double;
			Blob um_blob;
		}DataUnion;

	public:
		// Get the data flag
		inline DataFlag GetDataFlag();
		// if the data is null
		inline bool IsNull();
		// Get the data size
		inline int GetDataSize();
		// Clear data value
		void Clear();
		// Copy data value
		void Copy(const DataContainer& data);

	public:
		// Set data value
		bool SetData(unsigned __int64 value);
		bool SetData(double value);
		bool SetData(const string& str);
		bool SetData(const void* pointer, int data_size);
		// Get data value
		bool GetData(unsigned __int64& value);
		bool GetData(double& value);
		bool GetData(string& str);
		bool GetData(void*& pointer, int buffer_size);

	public:
		// Data value container
		DataValue m_data;
		// Data type flag
		DataFlag m_data_flag;
	};
	

	// Record data
	class _DATABASE Record
	{
	public:
		//
		Record(const Record& record);
		// Constructor
		Record();
		// Destructor
		~Record();

	public:
		// Get DataContainer reference, if not exist it will create a new DataContainer
		DataContainer& GetDataContainer(int index);
		// Add a column data by index
		bool AddColumnData(const DataContainer& column_data, int index);
		// Assign a column data value
		bool AssignColumnData(const DataContainer& column_data, int index);
		// Delete a column data by index
		bool DeleteColumnData(int index);
		// Clear all record data
		void ClearRecord();
		// Swap record data
		void SwapData(Record& record);

	public:
		// Record data: <index, data>
		typedef std::map<int, DataContainer> DataContainerMap;
		// The record data Container
		DataContainerMap m_record;
	};



	// Field information
	class _DATABASE Field
	{
	public:
		// Constructor
		Field(const char* field_name, FieldType type, FieldConstraint flag = EFC_None);
		// Default Constructor
		Field();
		// Copy Contructor
		Field(const Field& field);
		// Destructor
		~Field();
		// Table assign the value of the field index
		friend class Table;

	public:
		// Get the field name
		inline string GetFieldName();
		// Get the field index
		inline int GetFieldIndex();
		// Get the field user type
		inline FieldType GetFieldType();
		// Get the field constraint
		inline FieldConstraint GetFieldConstraint();
		// Clear the field
		inline void Clear();
		// Copy the field information
		inline void Copy(const Field& field);

	public:
		// Field name
		string m_name;
		// Field index
		int m_index;
		// Field user define type
		FieldType m_type;
		// Field constraint
		FieldConstraint m_constraint;
	};


	// Table information
	class _DATABASE Table
	{
	public:
		// Copy Contructor
		Table(const Table& table);
		// Constructor
		Table();
		// Destructor
		~Table();

	/* Define and Operation table field map and table name */
	public:
		// Table field map type
		typedef map<string, Field> FieldMap;
		// Table index type
		typedef map<int, string> TableIndex;
		// Table name
		string m_table_name;
		// Table field information
		FieldMap m_field_map;
	public:
		// Set table name
		void SetTableName(string table_name);
		// Get Table Name
		string GetTableName();
		// Add field to table
		bool AddField(Field& field);
		bool AddField(string field_name, FieldType type, FieldConstraint flag = EFC_None);
		// Get field from table
		bool GetField(string field_name, Field& field);
		bool GetField(int index, Field& field);
		// Remove field from table
		bool RemoveField(string field_name);
		bool RemoveField(int index);
		// Get count of table
		int GetFieldCount();
		// Copy the table field information
		void CopyTableInfo(Table& table);
		// Get the reference of FieldMap
		inline FieldMap& GetFieldMap();



	/* Define and operation on RecordColloction */
	public:
		// Table record collection type
		typedef vector<Record> RecordColloction;
		// Table data
		RecordColloction m_record_clt;
	public:
		// Append a new null record to the back of RecordColloction and return its reference
		Record& AppendNewRecord();
		// Append one record to the back of RecordColloction
		void AppendRecord(Record& record);
		// Clear the RecordColloction
		inline void ClearRecord();
		// Get the reference of RecordColloction
		inline RecordColloction& GetRecordColloction();
	};

}// _Database

#endif